package service

import (
	"context"
	"mini-app/config/mysql"
	"mini-app/internal/dal"
	"mini-app/internal/dao"
	"mini-app/internal/models"
	"strings"
)

type AdCoupon struct{}

func (AdCoupon) Create(ctx context.Context, name string, salesOff float32, startAt, endAt int64, deviceGroupID string) error {
	return dao.AdCouponDao{}.Create(ctx, dal.Q, name, salesOff, startAt, endAt, deviceGroupID)
}
func (AdCoupon) ModifyByID(ctx context.Context, id string, name string, salesOff float32, startAt, endAt int64, deviceGroupID string) error {
	return dao.AdCouponDao{}.ModifyByID(ctx, dal.Q, id, name, salesOff, startAt, endAt, deviceGroupID)
}
func (AdCoupon) DeleteByID(ctx context.Context, id string) error {
	return dao.AdCouponDao{}.DeleteByID(ctx, dal.Q, id)
}

func (AdCoupon) GetCouponsByContition(ctx context.Context, startTime, endAt int64, device_group_id, device_group_name, location_ids string) ([]*models.AdCoupon, error) {

	db := mysql.NewDB()
	if device_group_name != "" {
		group_id, _ := dao.PublishDeviceGroup{}.GetGroupIDByName(ctx, db, device_group_name)
		if group_id != "" {
			device_group_id = group_id
		}
	}

	return dao.AdCouponDao{}.GetByCondition(ctx, dal.Q, startTime, endAt, device_group_id, location_ids)
}

func (AdCoupon) GetCouponByContition(ctx context.Context, t int64, device_id, location_id string) (string, float32, int64, int64, error) {

	var price float32 = 0.0
	var start_at int64 = 0
	var end_at int64 = 0
	var name string = ""

	db := mysql.NewDB()
	deviceGroupIDsArr := dao.PublishDevice{}.GetGroupIDsByRobotNames(ctx, db, device_id)
	if len(deviceGroupIDsArr) == 0 {
		return name, price, start_at, end_at, nil
	}
	deviceGroupIDs := strings.Join(deviceGroupIDsArr, ",")

	coupons, err := dao.AdCouponDao{}.GetByCondition(ctx, dal.Q, t, 0, deviceGroupIDs, location_id)

	if len(coupons) > 0 {
		coupon := coupons[0]
		if err == nil {
			// price = basePrice * coupon.SalesOff
			price = coupon.SalesOff
			start_at = coupon.StartAt
			end_at = coupon.EndAt
			name = coupon.Name
		}
	}
	return name, price, start_at, end_at, nil
}

func (AdCoupon) GetTotalPriceByCoupon(ctx context.Context, startAt, endAt int64, device_ids, location_ids string) (float32, error) {
	// Get base price
	basePrice, err := AdConfig{}.GetBasePrice(ctx)
	if err != nil {
		return 0, err
	}

	var totalPrice float32 = 0

	duration := endAt - startAt
	// Convert duration from seconds to days, rounding up
	durationDays := int64((duration + 86399) / 86400) // 86400 seconds in a day, add 86399 to round up

	// Convert start time to days since epoch
	startDay := startAt/86400 + 1

	// Calculate price for each day
	for i := int64(0); i < durationDays; i++ {
		currentDay := startDay + i
		currentDayStart := currentDay * 86400

		deviceIDsSep := strings.Split(device_ids, ",")
		for _, deviceID := range deviceIDsSep {
			if deviceID != "" {
				_, price, _, _, _ := AdCoupon{}.GetCouponByContition(ctx, currentDayStart, deviceID, "")
				if price == 0 {
					totalPrice += basePrice
				} else {
					totalPrice += price
				}
			}
		}
	}

	return totalPrice, nil
}
